package com.lkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.lkd.common.VMSystem;
import com.lkd.config.ConsulConfig;
import com.lkd.config.TopicConfig;
import com.lkd.contract.OrderCheck;
import com.lkd.contract.VendoutContract;
import com.lkd.contract.VendoutData;
import com.lkd.dao.OrderDao;
import com.lkd.feign.UserService;
import com.lkd.vo.*;
import com.lkd.emq.MqttProducer;
import com.lkd.entity.OrderEntity;
import com.lkd.exception.LogicException;
import com.lkd.feign.VMService;
import com.lkd.service.OrderService;
import com.lkd.utils.DistributedLock;
import com.lkd.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    @Autowired
    private VMService vmService;

    @Autowired
    private UserService userService;
    @Autowired
    private MqttProducer mqttProducer;

    @Override
    public OrderEntity getByOrderNo(String orderNo) {
        QueryWrapper<OrderEntity> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(OrderEntity::getOrderNo,orderNo);
        return this.getOne(qw);
    }

    @Override
    public OrderEntity createOrder(PayVO payVO) {
        //（1）在订单服务类中，增加创建订单的方法，参数为PayVO （封装的支付对象）
        //
        //（2）创建订单逻辑1：通过远程调用vmService.hasCapacity 判断是否有库存 。
        if(!vmService.hasCapacity(payVO.getInnerCode(),Long.valueOf(payVO.getSkuId()))){
            throw new LogicException("库存已无");
        }
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOpenId(payVO.getOpenId());//openId
        orderEntity.setPayStatus(VMSystem.PAY_STATUS_NOPAY);//支付状态
        orderEntity.setOrderNo(payVO.getInnerCode()+System.nanoTime());//订单编号
        //（3）创建订单逻辑2：构建实体类OrderEntity，售货机相关信息通过 vmService.getVMInfo获得。
        VmVO vmVO = vmService.getVMInfo(payVO.getInnerCode());
        BeanUtils.copyProperties(vmVO,orderEntity);
        orderEntity.setAddr(vmVO.getNodeAddr());
        //（4）创建订单逻辑3：构建实体类OrderEntity，商品相关信息通过 vmService.getSku获得。
        SkuVO sku = vmService.getSku(payVO.getSkuId());
        BeanUtils.copyProperties(sku,orderEntity);
        orderEntity.setAmount(sku.getRealPrice());//价格
        orderEntity.setStatus(VMSystem.ORDER_STATUS_CREATE);
        //（5）创建订单逻辑4：通过userService.getPartner 获得合作商，使用提成比例计算分成。
        PartnerVO partner = userService.getPartner(vmVO.getOwnerId());
        BigDecimal bg = new BigDecimal(sku.getRealPrice());
        int bill = bg.multiply(new BigDecimal(partner.getRatio())).
                divide(new BigDecimal(100),0, RoundingMode.HALF_UP).intValue();
        orderEntity.setBill(bill);
        //（6）保存实体类。返回参数为订单实体类
        this.save(orderEntity);
        //将订单放到延迟队列中，10分钟后检查支付状态！！！！！！！！！！！！！！！！！！
        OrderCheck orderCheck = new OrderCheck();
        orderCheck.setOrderNo(orderEntity.getOrderNo());
        try {
            mqttProducer.send("$delayed/600/"+TopicConfig.ORDER_CHECK_TOPIC,2,orderCheck);
        } catch (Exception e) {
            log.error("send to emq error",e);
        }
        return orderEntity;
    }

}
